package com.smm.config.shiro;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ObjectReader;
import com.fasterxml.jackson.databind.json.JsonMapper;
import com.smm.config.JWTToken;
import com.smm.entity.User;
import com.smm.util.JwtUtils;
import io.jsonwebtoken.Claims;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;
import java.util.HashSet;
import java.util.Set;


public class JwtRealm extends AuthorizingRealm {

    private Logger logger = LoggerFactory.getLogger(JwtRealm.class);


    /**
     * 限定这个 Realm 只处理我们自定义的 JwtToken
     */
    @Override
    public boolean supports(AuthenticationToken token) {

        logger.info("JwtToken supports(AuthenticationToken token) ==> "+String.valueOf(token instanceof JWTToken));
        return token instanceof JWTToken;

    }

    /**
     * 默认使用此方法进行用户名正确与否验证，错误抛出异常即可。
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        logger.info("————身份认证方法————");
        String token = (String) authenticationToken.getCredentials();
        logger.info("token=========>>"+ token);

        return new SimpleAuthenticationInfo(token, token, "jwtRealm");
    }

    /**
     * 只有当需要检测用户权限的时候才会调用此方法，例如checkRole,checkPermission之类的
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        //System.out.println("————权限认证————");
        logger.info("————权限认证————");
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        String role = "null";
        //String username = JWTUtils.getokenContainValue(principals.toString());
        String token = String.valueOf(principals);
        logger.info(token);
        if (token.startsWith("Basic")){
            return info;
        }
        if (!token.startsWith(JwtUtils.TOKEN_PREFIX)){
            ObjectMapper objectMapper = new ObjectMapper();
            User user = objectMapper.convertValue(token, User.class);
            logger.info(String.valueOf(user));
            role = user.getRole();
        }

        try {
            Claims claims = JwtUtils.parseJwtRS256(token);
            String username = claims.get("username", String.class);
            role = claims.get("role",String.class);
            logger.info(username);
            logger.info(role);
        } catch (IOException e) {
            e.printStackTrace();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (InvalidKeySpecException e) {
            e.printStackTrace();
        }

        //获得该用户角色
       // String role = userMapper.getRole(username);
        //每个角色拥有默认的权限
       // String rolePermission = userMapper.getRolePermission(username);
        //每个用户可以设置新的权限
        //String permission = userMapper.getPermission(username);
        Set<String> roleSet = new HashSet<>();
        //Set<String> permissionSet = new HashSet<>();
        //需要将 role, permission 封装到 Set 作为 info.setRoles(), info.setStringPermissions() 的参数
       
        roleSet.add(role);
        //permissionSet.add(rolePermission);
       // permissionSet.add(permission);
        //设置该用户拥有的角色和权限
        info.setRoles(roleSet);
        //info.setStringPermissions(permissionSet);
        return info;
    }


}
